package com.ns.main;

import static com.ns.util.XwpfUtil.*;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFPicture;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ns.dao.model.VCommonArea;
import com.ns.dao.model.VObjQuestion;
import com.ns.dao.model.VPastpaperInfo;
import com.ns.dao.model.VTestpaperInfo;
import com.ns.service.QuestionService;
import com.ns.service.DataInitService;
import com.ns.service.VPastpaperService;
import com.ns.service.VTestPaperinfoService;
import com.ns.vo.QuestionDetailObject;

public class XingCeTestPaperExport {
	public static Map<Integer, String> AREAS = new HashMap<Integer, String>();
	public static Map<Integer, String> PARTS = new HashMap<Integer, String>();
	public static Map<Integer,String> MULTI = new HashMap<Integer, String>();;
	public static void main(String[] args) {
		@SuppressWarnings("resource")
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		QuestionService questionService = context.getBean(QuestionService.class);
		VTestPaperinfoService paperService = context.getBean(VTestPaperinfoService.class);
		DataInitService initService = context.getBean(DataInitService.class);

		// 初始化缓存映射数据
		AREAS = initService.findAllAreas();
		PARTS = initService.findAllPart();
		MULTI = initService.findAllMulti();
		
		List<VTestpaperInfo> papers = paperService.findAll();
		System.out.println(papers.size());
		for (VTestpaperInfo paper : papers) {
			try {
//				if(paper.getPukey()==3535){
//					exportPaper(paper, questionService);
//				}
				exportPaper(paper, questionService);
			} catch (Exception e) {
				System.out.println(paper.getPukey());
				e.printStackTrace();
			}
		}
	}

	public static void exportPaper(VTestpaperInfo paper, QuestionService questionService) throws IOException, InvalidFormatException {
		if(paper.getBlExamSub() != 1){
			return;
		}
		XWPFDocument doc = new XWPFDocument();

		XWPFParagraph paperInfo = doc.createParagraph();
		paperInfo.setAlignment(ParagraphAlignment.CENTER);
		// 标题
		createBoldRun(paperInfo, paper.getName(), 24, true).addBreak();
		// 试卷信息部分
		createBoldRun(paperInfo, "总分:", 12, false);
		createNormalRun(paperInfo, String.valueOf(paper.getTotalPoint()), 12, true);
		createBoldRun(paperInfo, "创建者:", 12, false);
		createNormalRun(paperInfo, String.valueOf(paper.getBb104()), 12, true);
		createBoldRun(paperInfo, "更新者:", 12, false);
		createNormalRun(paperInfo, String.valueOf(paper.getBb107()), 12, true);
		
		// 获取所有试题
		List<QuestionDetailObject> questions = questionService.findByTestPaper(paper.getPukey());
		int nowPart = 0;
		int nowMulti = 0;
		for (QuestionDetailObject question : questions) {
			XWPFParagraph questionPara = doc.createParagraph();
			questionPara.setAlignment(ParagraphAlignment.LEFT);
			questionPara.setSpacingBefore(5);
			if(question.getPart() != nowPart){
				createBoldRun(questionPara, PARTS.get(question.getPart()), 18, true);
				nowPart = question.getPart();
			}
			//材料
			if(question.getMuilti() == 1 && question.getMutiId() != nowMulti){
				createBoldRun(questionPara, "(复合题)", 10, false);
				writeHtml(doc,questionPara, MULTI.get(question.getMutiId()), 10);
				nowMulti = question.getMutiId();
			}
			if(question.getType() == null){
				continue;
			}
			createNormalRun(questionPara, String.valueOf(question.getDisOrder())+"、", 10, false);
			createBoldRun(questionPara, question.getType()==99?"(单选题)":"多选题", 10, false);
			writeHtml(doc,questionPara,question.getStem(),10);
			
			writeHtml(doc,questionPara,"A. "+question.getChoice1(),10);
			writeHtml(doc,questionPara,"B. "+question.getChoice2(),10);
			writeHtml(doc,questionPara,"C. "+question.getChoice3(),10);
			writeHtml(doc,questionPara,"D. "+question.getChoice4(),10);
			createNormalRun(questionPara, "", 14, true);
			createBoldRun(questionPara, "正确答案: ", 10, false);
			createNormalRun(questionPara, question.getStandAnswer(), 10, true);
			
			createBoldRun(questionPara, "知识点: ", 10, false);
			createNormalRun(questionPara, question.getPointPath(), 10, true);
			
			createBoldRun(questionPara, "难易: ", 10, false);
			createNormalRun(questionPara, question.getDifficult(), 10, true);
			
			createBoldRun(questionPara, "年份: ", 10, false);
			createNormalRun(questionPara, String.valueOf(question.getYear()), 10, true);
			
			createBoldRun(questionPara, "分数: ", 10, false);
			createNormalRun(questionPara, String.valueOf(question.getPoint()), 10, true);
			
			createBoldRun(questionPara, "解析: ", 10, false);
			writeHtml(doc, questionPara, question.getAnswerComment(), 10);
			
			createBoldRun(questionPara, "纠错: ", 10, false);
			writeHtml(doc, questionPara, question.getError(), 10);
			
			createBoldRun(questionPara, "释义: ", 10, false);
			writeHtml(doc, questionPara, question.getExplain(), 10);
			
			createBoldRun(questionPara, "技巧: ", 10, false);
			writeHtml(doc, questionPara, question.getSkill(), 10);
			
			createBoldRun(questionPara, "拓展: ", 10, false);
			writeHtml(doc, questionPara, question.getExpand(), 10);
			
			createBoldRun(questionPara, "作者: ", 10, false);
			createNormalRun(questionPara, question.getAuthor(), 10, true);
			
			createBoldRun(questionPara, "来源: ", 10, false);
			createNormalRun(questionPara, question.getSource(), 10, true);
			
			createBoldRun(questionPara, "讨论: ", 10, false);
			writeHtml(doc, questionPara, question.getFb1z2(), 10);
			createNormalRun(questionPara, question.getFb1z2(), 10, true);
			
			createBoldRun(questionPara, "视频: ", 10, false);
			createNormalRun(questionPara, question.getFb1z3(), 10, true);
			
		}
		// 输出
		FileOutputStream out = new FileOutputStream("f:/武汉/模拟题行测/" + paper.getName().replaceAll("\\\\", "-").replaceAll("/", "-")+"_"+paper.getPukey()+ ".doc");
		doc.write(out);
		out.close();
	}
	
	public static String convertHtmlText(String text){
		if(text == null){
			return "";
		}
		//保留换行符
		text = text.replaceAll("<\\s*/\\s*p\\s*>", "{nl::ln}");
		//保留图片
		formatImg(text);
		text = text.replaceAll("<[a-z]+[^>]*>", "").replaceAll("<[^>]*/[^>]*>", "").replaceAll("&nbsp;", " ");
		return text;
	}
	
	public static String formatImg(String str) {
		Pattern imgPat = Pattern.compile("<!--\\s*\\[\\s*i+\\s*m+\\s*g+[^>]*\\]\\s*([0-9a-zA-Z\\.]+)\\s*\\[\\s*/\\s*i+\\s*m+\\s*g+\\s*\\]\\s*-->");
		Matcher stemMatcher = imgPat.matcher(str);
		while (stemMatcher.find()) {
			String temp = stemMatcher.group(1).trim();
			String newStr = "{img:"+ temp.substring(0, 1) + "/" + temp + "}";
			String oldStr = stemMatcher.group(0);
			str = str.replace(oldStr, newStr);
		}
		return str;
	}
	
	/*public static void writeHtml(XWPFDocument doc,XWPFParagraph para,String value,int fontSize) throws IOException, InvalidFormatException{
		value = convertHtmlText(formatImg(value)).trim();
		
		String imgReg = "\\{img\\:([^\\}]+)\\}";
		String [] strs = value.split("\\{nl::ln\\}");
		for(String str : strs){
			if(str.replaceAll(imgReg, "").equals("")){
				continue;
			}
			createNormalRun(para, str.replaceAll(imgReg, ""), fontSize, true);
		}
		Pattern imgPat = Pattern.compile(imgReg);
		Matcher stemMatcher = imgPat.matcher(value);
		while (stemMatcher.find()) {
			String imgStr = stemMatcher.group(1);
			XWPFRun run = para.createRun();
			String fileName = "F:\\武汉\\images\\vhuatu\\tiku\\"+imgStr;
			BufferedImage img = ImageIO.read(new File(fileName));
			int width = img.getWidth();
			int height = img.getHeight();
			InputStream is = new FileInputStream(fileName);
			String picId = doc.addPictureData(is, XWPFDocument.PICTURE_TYPE_PNG);
			createPicture(run, picId, doc.getNextPicNameNumber(XWPFDocument.PICTURE_TYPE_PNG), width, height);
			run.addBreak();
		}
		
	}*/
	
	/**
	 * convertHtmlText(formatImg(value)).trim();
	 * @param doc
	 * @param para
	 * @param value
	 * @param fontSize
	 * @throws IOException
	 * @throws InvalidFormatException
	 */
	public static void writeHtml(XWPFDocument doc,XWPFParagraph para,String value,int fontSize){
		if(StringUtils.isBlank(value)){
			createNormalRun(para, "", fontSize, true);
			return;
		}
		value = convertHtmlText(formatImg(value)).trim();
		String [] strs = value.split("\\{nl::ln\\}");
		for(String str : strs){
			try {
				writePricture(doc, para, str, fontSize);
			} catch (Exception e) {
				System.out.println(str);
			}
		}
		
	}
	
	public static void writePricture(XWPFDocument doc,XWPFParagraph para,String value,int fontSize) throws IOException, InvalidFormatException{
		if(StringUtils.isBlank(value)){
			return;
		}
		String imgReg = "\\{img\\:([^\\}]+)\\}";
		Pattern imgPat = Pattern.compile(imgReg);
		Matcher stemMatcher = imgPat.matcher(value);
		boolean flag = false;
		while (stemMatcher.find()) {
			flag = true;
			String sub = stemMatcher.group(0);
			String imgStr = stemMatcher.group(1);
			//输出前面的文本
			createNormalRun(para, value.substring(0, value.indexOf(sub)), fontSize, false);
			//输出图片
			XWPFRun run = para.createRun();
			String fileName = "F:\\武汉\\images\\vhuatu\\tiku\\"+imgStr;
			BufferedImage img = ImageIO.read(new File(fileName));
			int width = img.getWidth();
			int height = img.getHeight();
			InputStream is = new FileInputStream(fileName);
			String picId = doc.addPictureData(is, XWPFDocument.PICTURE_TYPE_PNG);
			createPicture(run, picId, doc.getNextPicNameNumber(XWPFDocument.PICTURE_TYPE_PNG), width, height);
			writePricture(doc, para, value.substring(value.indexOf(sub)+sub.length(),value.length()), fontSize);
			is.close();
			break;
		}
		if(!flag){
			createNormalRun(para, value, fontSize, false);
		}
		createNormalRun(para, "", fontSize, true);
	}
}
